﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Servidor.Objectos;
using TiposComuns.Objectos;
using Servidor.Objectos.Pesquisa;
using Servidor.Objectos.Actions;

namespace Servidor.WebServices
{
    /// <summary>
    /// Interface for services provided between servers, 
    /// in the peer to peer network.
    /// </summary>
    public interface IPeer
    {
        #region Meta
        void SetView(View view);

        void RollBack(IDMsg id);

        /// <summary>
        /// Setes the state of the server
        /// </summary>
        /// <param name="state">New state</param>
        void SetState(State state);

        /// <summary>
        /// Checks if the state of the sender is consistent with the server.
        /// </summary>
        /// <param name="state">State of the sender</param>
        /// <returns>Reply that contains the state of the receiver and a possible
        /// list of actions, in order to synchronize
        /// </returns>
        Synchronization CheckView(State state, int id);

        /// <summary>
        /// Synchronizes the receiver by sending the actions it should execute,
        /// to update it's state.
        /// </summary>
        /// <param name="actions">List of new actions to execute</param>
        void Synchronize(List<Servidor.Objectos.Action> actions);

        /// <summary>
        /// Update replica
        /// </summary>
        /// <param name="sync"></param>
        Synchronization Update(int serv,Synchronization sync);


        /// <summary>
        /// Exit a server
        /// </summary>
        /// <param name="id">identifier of the server that exits</param>
        void ServerExit(int id);

        /// <summary>
        /// Remove the pendent requests
        /// </summary>
        /// <param name="pends">Pendent requests</param>
        void RemovePendents(List<int> pends);

        bool isAlive();
        #endregion

        #region Profile
        Profile GetProfile();
        #endregion

        #region Posts
        /// <summary>
        /// Returns list of posts which identifier
        /// is greater than the provided
        /// </summary>
        /// <param name="last">Identifier of the last post sent</param>
        /// <returns>List of recent posts</returns>
        List<Post> PostsSince(string user,int last);
        #endregion

        #region Friends
        /// <summary>
        /// Receives a friend request
        /// </summary>
        /// <param name="sender">Person who sends the request</param>
        bool FriendReceive(Person sender);

        /// <summary>
        /// Acceptance of a friendship request
        /// </summary>
        /// <param name="sender">Person who accepts the new friendship</param>
        bool BeAccepted(Person sender);

        /// <summary>
        /// Rejection of a friendship request
        /// </summary>
        /// <param name="sender">Person who rejected the new friendship</param>
        bool BeRejected(Person sender);
        #endregion

        #region Search
        void SetTree(KTree tree);

        /// <summary>
        /// Returns the k closest nodes to person, known locally
        /// </summary>
        /// <param name="person">Searched person</param>
        /// <returns>k closes nodes</returns>
        KClosest GetClosest(byte []hash);

        /// <summary>
        /// Stores a new person for a given property.
        /// Ensures that this person is inserted, even if
        /// the local list is full
        /// </summary>
        /// <param name="key">Property's key</param>
        /// <param name="person">New person</param>
        KeyValuePair<SearchResult,bool> StoreSearched(byte[] key, Person person);

        /// <summary>
        /// Propagates it's own list
        /// </summary>
        /// <param name="key">Property's key</param>
        /// <param name="persons">List</param>
        SearchResult Store(byte []key,SearchResult res);

        
        /// <summary>
        /// Disassociates a person from a property
        /// </summary>
        /// <param name="key">Property's hash</param>
        /// <param name="person">Removed person</param>
        KeyValuePair<SearchResult, bool> RemoveSearched(byte[] key, Person person);

        /// <summary>
        /// Returns part of the distributed list of 
        /// people that have a searched property.
        /// </summary>
        /// <param name="key">Property's hash</param>
        /// <returns>List of people that have the property</returns>
        SearchResult GetSearched(byte []key);

        #endregion        
    }
}
